Skip to content

feat(aux-audit): score agent-spec v1 — authority, not labels (0.2.0) - #14

Merged
RevenuePuzzles merged 1 commit into
mainfrom
claude/aux-audit-v1-scoring
Sep 4, 2026
Merged

feat(aux-audit): score agent-spec v1 — authority, not labels (0.2.0)#14
RevenuePuzzles merged 1 commit into
mainfrom
claude/aux-audit-v1-scoring

Conversation

@RevenuePuzzles

Copy link
Copy Markdown
Contributor

What this PR does

Closes the last half of #10. aux.H01 and aux.H03 stop asking "what did you call your autonomy level" and start asking what a v1 spec actually declares: per-action authority, the mechanism enforcing each row, and the five forms of human control.

Both spec versions are scored, detected from the document rather than the filename.

Architecture

Both versions normalise into one evidence model (src/evidence.ts) that the rules read. One rule set instead of two, and the difference between what v0 and v1 can express becomes a visible, tested mapping rather than branching scattered through the rules.

Where a version cannot express something, the field is absent and the rule says so. It never scores absence of a field as absence of a mechanism.

What v1 makes computable that v0 could not

  • aux.H05 reports the capability/mandate gap. The schema header calls it the attack surface; it is now a number with the ungoverned capabilities named. On the weak fixture: "2 capabilities the credentials grant but no mandate governs: delete_email, calendar_event".
  • A row enforced by "the system prompt" counts as unenforced, per trust-architecture.yaml: a prompt is a request, a tool boundary is a control.
  • aux.H04 reads consequence_scaled_approval and whether authority varies across actions at all. A single authority for every action is the slider the canon rejects, wearing a table.
  • aux.H07 requires an escalation to name both a recipient and on_timeout, because without it "ask a human" is a queue that fills up.

Two findings that changed the design

1. v1 has no memory field. Not memory: false — no field at all. aux.H08 is therefore reported as not scoreable rather than scored zero. A consequence worth stating plainly: three of the twelve taxonomy gaps (memory_amnesia, preference_ignored, context_leak) are unreachable from a v1 spec. That is a coverage regression in the schema, not in the tool, and it is noted on #10.

2. A trust stage backed only by an unscoreable heuristic was being reported as EARNED.

aux.T02 Contextual Trust depends solely on aux.H08. With H08 inapplicable the shortfall list came back empty, and empty read as success — so every v1 spec was silently earning contextual trust on zero evidence. A claim dressed as a finding, which is the exact failure this taxonomy exists to name.

Stages now carry assessable. An unassessable stage is never earned, and it stops the ladder the way a broken one does:

| 1. Functional Trust  | ✅ | — |
| 2. Contextual Trust  | —  | not assessable: `aux.H08` could not be scored |
| 3. Judgment Trust    | ❌ | an earlier stage — trust is sequential |

Two regression tests pin it. No issue is raised against the product for an unassessable stage — it is the format's limit, not the agent's failing.

v0 is unchanged

Same fixtures, same scores, same evidence strings: strong-spec 100/A/advocacy, weak-spec 4/F/none. meta.spec_version records which format produced a report, since scores are not comparable across the two.

Linked Issue

Closes #10.

Type

  • New pattern
  • New gap
  • Teardown
  • Framework edit (must include rationale, ID migration note if renamed, updated examples)
  • Schema fix
  • Doc fix / typo / link
  • Other

Migration note: no IDs renamed and no schema changed. aux-audit goes to 0.2.0 because what aux.H01, aux.H03, aux.H04, aux.H05, aux.H07 and aux.H10 measure under v1 differs from v0, so scores are not comparable across formats. v0 specs keep scoring identically to 0.1.x.

Contribution bar — checklist

  • I've read CONTRIBUTING.md.
  • If this introduces or renames an ID, I opened a debate Issue first. — none; [debate] agent-spec v1: per-action mandate with enforced_by, replacing the autonomy label #10 settled the vocabulary before any of this.
  • If this adds a pattern, it has a diagram, a runnable example, and an anti-pattern. — n/a.
  • If this adds a gap, it has a reproducible scenario and references a heuristic or trust stage. — n/a.
  • CI passes (schema validation, link check). — verified locally: 48 tests (up from 38), schemas/validate.py PASSED, check-coverage.py 12/12, yamllint clean, check:schemas clean, links resolve.
  • No emoji in code or schemas.
  • Short sentences. Named things over adjectives.

New dependency

ajv for real draft 2020-12 validation — the package had exactly one runtime dependency (yaml) and now has two. format: date on shutdown.last_tested is implemented rather than ignored, so ajv stops logging that it is skipping a format on every run.

Out of scope

  • A memory block for v1. The fix for finding 1 is a schema change, and it belongs in its own discussion rather than inside a scoring PR.
  • trust_stage in the input. [debate] agent-spec v1: per-action mandate with enforced_by, replacing the autonomy label #10 asked whether an input format should carry the audit's own output, and if so whether the tool should report the gap between claimed and supported stage. The field is read into evidence but nothing acts on it yet. "You declare aux.T03; the spec supports aux.T01" is still the most useful line this tool could print.

🤖 Generated with Claude Code

https://claude.ai/code/session_01MhpqWEvwKp7NrmJfdXYq4M


Generated by Claude Code

Closes the last half of #10. aux.H01 and aux.H03 stop asking "what did
you call your autonomy level" and start asking what a v1 spec actually
declares: per-action authority, the mechanism enforcing each row, and the
five forms of human control.

Architecture: both versions normalise into one evidence model
(src/evidence.ts) that the rules read. One rule set instead of two, and
the difference between what v0 and v1 can express becomes a visible,
tested mapping rather than branching scattered through the rules. Where a
version cannot express something, the field is absent and the rule says
so — it never scores absence of a *field* as absence of a *mechanism*.

What v1 makes computable that v0 could not:

- aux.H05 reports the gap between what the credentials permit and what
  the mandate governs. The schema calls that the attack surface; it is
  now a number with the ungoverned capabilities named.
- a row enforced by "the system prompt" is reported as unenforced, per
  trust-architecture: a prompt is a request, a tool boundary is a
  control.
- aux.H04 reads consequence_scaled_approval and whether authority varies
  across actions at all — a single authority for every action is the
  slider the canon rejects, wearing a table.
- aux.H07 requires an escalation to name both a recipient and what
  happens on timeout, because without on_timeout "ask a human" is a
  queue that fills up.

Two findings that changed the design:

1. v1 has no memory field. Not "memory: false" — no field. aux.H08 is
   therefore reported as not scoreable rather than scored zero, and a
   quarter of the taxonomy (memory_amnesia, preference_ignored,
   context_leak) is unreachable from a v1 spec. Worth fixing in the
   schema; noted in #10.

2. A trust stage backed only by an unscoreable heuristic was being
   reported as EARNED. aux.T02 Contextual Trust depends solely on
   aux.H08, so every v1 spec was silently earning contextual trust on
   zero evidence — a claim dressed as a finding, which is the exact
   failure this taxonomy exists to name. Stages now carry `assessable`,
   an unassessable stage is never earned, and it stops the ladder the way
   a broken one does. Two regression tests pin it.

v0.1.0 scoring is unchanged: same fixtures, same scores, same evidence
strings. meta.spec_version records which format produced a report, since
scores are not comparable across the two.

48 tests, up from 38. ajv added for real draft 2020-12 validation, with
`format: date` implemented rather than ignored.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MhpqWEvwKp7NrmJfdXYq4M
@RevenuePuzzles
RevenuePuzzles merged commit be5fff8 into main Sep 4, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[debate] agent-spec v1: per-action mandate with enforced_by, replacing the autonomy label

2 participants